﻿using Microsoft.Reporting.WinForms;
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using TurtleEngine;
using TurtleEngine.Helper.CHMWriter;

namespace Turtle
{
	 /// <summary>
	 ///
	 /// </summary>
	 public class Helper
	 {
		  /// <summary>
		  /// Enables the format.
		  /// </summary>
		  /// <param name="viewer">The viewer.</param>
		  /// <param name="formatName">Name of the format.</param>
		  public static void EnableFormat(ReportViewer viewer, string formatName)
		  {
				const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
				FieldInfo m_previewService = viewer.LocalReport.GetType().GetField("m_previewService", Flags);
				MethodInfo ListRenderingExtensions = m_previewService.FieldType.GetMethod("ListRenderingExtensions", Flags);
				object previewServiceInstance = m_previewService.GetValue(viewer.LocalReport);
				var extensions = ListRenderingExtensions.Invoke(previewServiceInstance, null) as IList;
				PropertyInfo name = extensions[0].GetType().GetProperty("Name", Flags);

				foreach (object extension in extensions)
				{
					 if (string.Compare(name.GetValue(extension, null).ToString(), formatName, true) == 0)
					 {
						  FieldInfo m_isVisible = extension.GetType().GetField("m_isVisible", BindingFlags.NonPublic | BindingFlags.Instance);
						  FieldInfo m_isExposedExternally = extension.GetType()
																	  .GetField("m_isExposedExternally", BindingFlags.NonPublic | BindingFlags.Instance);
						  m_isVisible.SetValue(extension, true);
						  m_isExposedExternally.SetValue(extension, true);
						  break;
					 }
				}
		  }

		  /// <summary>
		  /// Gets the OS version.
		  /// </summary>
		  /// <returns></returns>
		  public static OSVersion GetOSVersion()
		  {
				var version = OSVersion.Unknown;
				switch (Environment.OSVersion.Platform)
				{
					 case PlatformID.Win32S:
						  version = OSVersion.Windows3_1;
						  break;

					 case PlatformID.Win32Windows:
						  switch (Environment.OSVersion.Version.Minor)
						  {
								case 0:
									 version = OSVersion.Windows95;
									 break;

								case 10:
									 if (Environment.OSVersion.Version.Revision.ToString() == "2222A")
										  version = OSVersion.Windows98SecondEdition;
									 else
										  version = OSVersion.Windows98;
									 break;

								case 90:
									 version = OSVersion.WindowsME;
									 break;
						  }
						  break;

					 case PlatformID.Win32NT:
						  switch (Environment.OSVersion.Version.Major)
						  {
								case 3:
									 version = OSVersion.WindowsNT3_51;
									 break;

								case 4:
									 version = OSVersion.WindowsNT4_0;
									 break;

								case 5:
									 switch (Environment.OSVersion.Version.Minor)
									 {
										  case 0:
												version = OSVersion.Windows2000;
												break;

										  case 1:
												version = OSVersion.WindowsXP;
												break;

										  case 2:
												version = OSVersion.Windows2003;
												break;
									 }
									 break;

								case 6:
									 switch (Environment.OSVersion.Version.Minor)
									 {
										  case 0:
												version = OSVersion.WindowsVista;
												break;

										  case 1:
												version = OSVersion.Windows7;
												break;
									 }
									 break;
						  }
						  break;

					 case PlatformID.WinCE:
						  version = OSVersion.WindowsCE;
						  break;

					 case PlatformID.Unix:
						  version = OSVersion.Unix;
						  break;
				}
				return version;
		  }

		  /// <summary>
		  /// Gets the program files.
		  /// </summary>
		  /// <returns></returns>
		  public static string GetProgramFiles()
		  {
				string programFiles = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
				if (programFiles == null)
					 programFiles = Environment.GetEnvironmentVariable("ProgramFiles");

				return programFiles;
		  }

		  /// <summary>
		  /// Joins all data tables.
		  /// </summary>
		  public static void JoinAllDataTables()
		  {
				//entireDatabase.Tables.Add(instanceInformation);
				//entireDatabase.Tables.Add(dataSourceInformation);
				//entireDatabase.Tables.Add(dataTypes);
				//entireDatabase.Tables.Add(restrictions);
				//entireDatabase.Tables.Add(reservedWords);
				//entireDatabase.Tables.Add(users);
				//entireDatabase.Tables.Add(databases);

				//entireDatabase.Tables.Add(tables);
				//entireDatabase.Tables.Add(columns);
				//entireDatabase.Tables.Add(allColumns);
				//entireDatabase.Tables.Add(columnSetColumns);
				//entireDatabase.Tables.Add(structuredTypeMembers);
				//entireDatabase.Tables.Add(views);
				//entireDatabase.Tables.Add(viewColumns);
				//entireDatabase.Tables.Add(procedureParameters);
				//entireDatabase.Tables.Add(procedures);
				//entireDatabase.Tables.Add(foreignKeys);
				//entireDatabase.Tables.Add(indexColumns);
				//entireDatabase.Tables.Add(indexes);
				//entireDatabase.Tables.Add(userDefinedTypes);

				//File.WriteAllText(@"xml\entireDB.xml", entireDatabase.GetXml());
		  }

		  /// <summary>
		  /// Writes the CHM help.
		  /// </summary>
		  /// <param name="chmFileName">Name of the CHM file.</param>
		  public static void WriteCHMHelp(string chmFileName)
		  {
				var hhc = new HHCWriter(Utility.DatabaseName + ".hhc", Utility.DatabaseName + ".hhp", Utility.DatabaseName + ".chm");
				hhc.Write();
				CompileCHMHelp(chmFileName);
		  }

		  /// <summary>
		  /// Compiles the CHM help.
		  /// </summary>
		  /// <param name="chmFileName">Name of the CHM file.</param>
		  private static void CompileCHMHelp(string chmFileName)
		  {
				StreamReader rd = null;
				string location = Assembly.GetExecutingAssembly().Location;
				location = location.Substring(0, location.LastIndexOf("\\"));

				var startInfo = new ProcessStartInfo();
				startInfo.CreateNoWindow = true; // false;
				startInfo.FileName = GetProgramFiles() + @"\HTML Help Workshop\hhc.exe";
				startInfo.WindowStyle = ProcessWindowStyle.Hidden; // ProcessWindowStyle.Normal;
				startInfo.UseShellExecute = false;
				startInfo.RedirectStandardOutput = true;
				startInfo.Arguments = "\"" + location + "\\" + Utility.DatabaseName + ".hhp" + "\"";

				//MessageBox.Show(startInfo.Arguments);
				try
				{
					 using (Process exeProcess = Process.Start(startInfo))
					 {
						  exeProcess.WaitForExit();

						  rd = exeProcess.StandardOutput;

						  //MessageBox.Show("StandardOutput: " + rd.ReadToEnd());

						  File.Copy(location + "\\" + Utility.DatabaseName + ".chm", chmFileName);
					 }
				}
				catch (Exception ex)
				{
					 MessageBox.Show(ex.Message + rd != null ? rd.ReadToEnd() : string.Empty);
				}
		  }
	 }
}